<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // ES5 
    // 对象取值
    // var zhang = {
    //     name: "张三",
    //     age: 18,
    //     height: "172cm",
    //     weight: "70kg",
    // }
    // 从对象中取值 => 赋值给变量
    // var name = zhang.name;
    // var age = zhang.age;
    // var height = zhang.height;
    // var weight = zhang.weight;



    // ES6 解构赋值
    // ES6 允许按照一定模式，从数组和对象中提取值，对变量进行赋值，这被称为解构（Destructuring）。
    // 本质上，这种写法属于“模式匹配”，只要等号两边的模式相同，左边的变量就会被赋予对应的值。

    // 对象解构  => 对应键名解构

    var zhang = { name: "张三", age: 18, height: "172cm", weight: "70kg" };

    // 对应键名解构 (结构简单 => 键名对应变量名)
    var { name, age, height, weight } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, age, height, weight);
    // 等价于
    // var { name: name, age: age, height: height, weight: weight } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }

    // 自定义变量名 (没有简写 => 自定义变量名)
    // 1. 变量名已被使用过 => 自定义一个新的
    // 2. 对象的键名是关键字/保留字 -> 无法作为变量 -> 自定义一个新的

    // var { name: a, age: b, height: c, weight: d } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(a, b, c, d);

    // var { name, age, class: _class, height, weight } = { name: "张三", age: 18, class: "2215", height: "172cm", weight: "70kg" }
    // console.log(name, age, _class, height, weight);


    // 完全解构
    // var { name, age, height, weight } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, age, height, weight);

    // 不完全解构
    // var { name, height } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, height);


    // 解构不成功 => 返回undefined
    // var { name, age, height, weight, hobby } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, age, height, weight, hobby);


    // 解构过程中 可以给变量设置默认值
    // var { name, age, height, weight, hobby = "sing" } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, age, height, weight, hobby);


    // 对象解构需注意,不能对null和undefined解构

    // 解构不成功 => undefined
    // var { a } = 1;   // 数字也是一个特殊的对象 num.toFixed()  num.toString()
    // console.log(a, 1["a"]); // undefined

    // var { a } = "hello";   // 数字也是一个特殊的对象 num.toFixed()  num.toString()
    // console.log(a, 1["a"]); // undefined

    // var { a } = true;   // 数字也是一个特殊的对象 num.toFixed()  num.toString()
    // console.log(a, 1["a"]); // undefined


    // var { a } = null;
    // var { a } = undefined;


    // 对象解构高级(配合扩展运算符  => Rest参数 => 合并剩余参数)
    // Rest参数必须放在解构的最后方

    // name => "张三"
    // age  => 18
    // ...info =>  height: "172cm", weight: "70kg" 
    // var { name, age, ...info } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, age, info);

    // Rest参数必须放在解构的最后方
    // var { name, ...info, age } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, age, info);

    // var { name, height, ...info } = { name: "张三", age: 18, height: "172cm", weight: "70kg" }
    // console.log(name, height, info);


    // 对象中包含其他对象/数组 如何解构
    var zhang = {
        name: "张三",
        age: 18,
        info: {
            height: "172cm",
            weight: "70kg"
        },
        grade: {
            ch: 55,
            mh: 66,
            eh: 77
        },
        hobby: ["sing", "dance", "rap"]
    }

    // 分步解构
    // var { name, age, info, grade, hobby } = zhang;
    // console.log(name, age, info, grade, hobby);

    // var { height, weight } = info;
    // var { ch, mh, eh } = grade;
    // var [h1, h2, h3] = hobby;
    // console.log(height, weight);
    // console.log(ch, mh, eh);
    // console.log(h1, h2, h3);

    // 一步到位 
    // 注意: 如果需要对 对象中的数据进行二次解构,需要对应键名解构键值
    var { name, age, info: { height, weight }, grade: { ch, mh, eh }, hobby: [h1, h2, h3] } = zhang;
    console.log(name, age, height, weight, ch, mh, eh, h1, h2, h3);


    let obj = {
        p: [
            'Hello',
            { y: 'World' }
        ]
    };

    // var { p: p } = obj;
    // var { p: [x, { y }] } = obj;
    // console.log(x, y);

    const node = {
        loc: {
            start: {
                line: 1,
                column: 5
            }
        }
    };

    var { loc: loc } = node;
    var { loc: { start: start } } = node;
    var { loc: { start: { line, column } } } = node;
    console.log(line, column);
</script>

</html>